package zgrjb.snbq.teach_platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import zgrjb.snbq.teach_platform.dto.model.ConversationDO;
import zgrjb.snbq.teach_platform.dto.model.MessageDO;
import zgrjb.snbq.teach_platform.dto.model.UserDO;
import zgrjb.snbq.teach_platform.mapper.ConversationMapper;
import zgrjb.snbq.teach_platform.mapper.MessageMapper;
import zgrjb.snbq.teach_platform.mapper.UserMapper;
import zgrjb.snbq.teach_platform.service.MessageService;
import zgrjb.snbq.teach_platform.util.IDUtil;
import zgrjb.snbq.teach_platform.util.JsonData;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 消息服务实现类
 * 
 * @author system
 * @since 2024-12-28
 */
@Slf4j
@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private ConversationMapper conversationMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    @Transactional
    public JsonData sendPrivateMessage(Long fromUserId, Long toUserId, String content, String contentType) {
        try {
            // 1. 验证用户是否存在
            UserDO fromUser = userMapper.selectById(fromUserId);
            UserDO toUser = userMapper.selectById(toUserId);
            if (fromUser == null || toUser == null) {
                return JsonData.buildError("用户不存在");
            }

            // 2. 创建或获取会话
            String conversationId = getOrCreateConversation(fromUserId, toUserId);

            // 3. 创建消息
            MessageDO message = MessageDO.builder()
                .id((Long) IDUtil.geneSnowFlakeID())
                .fromUserId(fromUserId)
                .toUserId(toUserId)
                .messageType("private")
                .content(content)
                .contentType(contentType != null ? contentType : "text")
                .conversationId(conversationId)
                .isRead(0)
                .priority(1)
                .isDeleted(0)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

            messageMapper.insert(message);

            // 4. 更新会话最后消息时间
            updateConversationLastMessage(conversationId, message.getId());

            log.info("发送私聊消息成功，消息ID: {}", message.getId());
            return JsonData.buildSuccess(message);

        } catch (Exception e) {
            log.error("发送私聊消息失败", e);
            return JsonData.buildError("发送消息失败");
        }
    }

    @Override
    public JsonData getUserMessages(Long userId, int page, int size) {
        try {
            Page<MessageDO> pageParam = new Page<>(page, size);
            QueryWrapper<MessageDO> wrapper = new QueryWrapper<>();
            wrapper.and(w -> w.eq("from_user_id", userId).or().eq("to_user_id", userId))
                   .eq("is_deleted", 0)
                   .orderByDesc("create_time");

            IPage<MessageDO> result = messageMapper.selectPage(pageParam, wrapper);

            Map<String, Object> data = new HashMap<>();
            data.put("list", result.getRecords());
            data.put("total", result.getTotal());
            data.put("current", result.getCurrent());
            data.put("size", result.getSize());

            return JsonData.buildSuccess(data);

        } catch (Exception e) {
            log.error("获取用户消息失败", e);
            return JsonData.buildError("获取消息失败");
        }
    }

    @Override
    @Transactional
    public JsonData markAsRead(Long messageId, Long userId) {
        try {
            MessageDO message = messageMapper.selectById(messageId);
            if (message == null || !message.getToUserId().equals(userId)) {
                return JsonData.buildError("消息不存在或无权限");
            }

            message.setIsRead(1);
            message.setReadTime(LocalDateTime.now());
            message.setUpdateTime(LocalDateTime.now());
            messageMapper.updateById(message);

            return JsonData.buildSuccess("标记已读成功");

        } catch (Exception e) {
            log.error("标记消息已读失败", e);
            return JsonData.buildError("标记已读失败");
        }
    }

    @Override
    public JsonData getUnreadCount(Long userId) {
        try {
            QueryWrapper<MessageDO> wrapper = new QueryWrapper<>();
            wrapper.eq("to_user_id", userId)
                   .eq("is_read", 0)
                   .eq("is_deleted", 0);

            Long count = messageMapper.selectCount(wrapper);
            return JsonData.buildSuccess(count);

        } catch (Exception e) {
            log.error("获取未读消息数量失败", e);
            return JsonData.buildError("获取未读数量失败");
        }
    }

    @Override
    @Transactional
    public JsonData deleteMessage(Long messageId, Long userId) {
        try {
            MessageDO message = messageMapper.selectById(messageId);
            if (message == null || (!message.getFromUserId().equals(userId) && !message.getToUserId().equals(userId))) {
                return JsonData.buildError("消息不存在或无权限");
            }

            message.setIsDeleted(1);
            message.setUpdateTime(LocalDateTime.now());
            messageMapper.updateById(message);

            return JsonData.buildSuccess("删除消息成功");

        } catch (Exception e) {
            log.error("删除消息失败", e);
            return JsonData.buildError("删除消息失败");
        }
    }

    @Override
    public JsonData searchUsers(String keyword, String userType) {
        try {
            QueryWrapper<UserDO> wrapper = new QueryWrapper<>();
            wrapper.and(w -> w.like("name", keyword)
                              .or().like("phone", keyword)
                              .or().like("email", keyword)
                              .or().like("student_id", keyword)
                              .or().like("teacher_no", keyword));
            if (userType != null && !userType.isEmpty()) {
                wrapper.eq("type", userType);
            }
            wrapper.eq("status", 1)
                   .select("id", "name", "type", "title", "teacher_no", "phone", "email", "head_img", "department");
            List<UserDO> users = userMapper.selectList(wrapper);
            // 只返回公开字段
            List<Map<String, Object>> result = users.stream().map(u -> {
                Map<String, Object> map = new HashMap<>();
                map.put("id", u.getId());
                map.put("name", u.getName());
                map.put("type", u.getType());
                map.put("title", u.getTitle());
                map.put("teacherNo", u.getTeacherNo());
                map.put("phone", u.getPhone());
                map.put("email", u.getEmail());
                map.put("headImg", u.getHeadImg());
                map.put("department", u.getDepartment());
                return map;
            }).collect(Collectors.toList());
            return JsonData.buildSuccess(result);
        } catch (Exception e) {
            log.error("搜索用户失败", e);
            return JsonData.buildError("搜索用户失败");
        }
    }

    @Override
    public JsonData getConversations(Long userId) {
        try {
            QueryWrapper<ConversationDO> wrapper = new QueryWrapper<>();
            // 修复查询逻辑：查找包含当前用户的会话
            wrapper.and(w -> w.like("participants", "[" + userId + ",")
                              .or().like("participants", "," + userId + "]")
                              .or().like("participants", "[" + userId + "]"))
                   .eq("is_active", 1)
                   .orderByDesc("last_message_time");

            List<ConversationDO> conversations = conversationMapper.selectList(wrapper);

            // 补充会话信息
            List<Map<String, Object>> result = conversations.stream().map(conv -> {
                Map<String, Object> convInfo = new HashMap<>();
                convInfo.put("id", conv.getId());
                convInfo.put("type", conv.getType());
                convInfo.put("title", conv.getTitle());
                convInfo.put("avatar", conv.getAvatar());
                convInfo.put("lastMessageTime", conv.getLastMessageTime());
                
                // 获取最后一条消息
                if (conv.getLastMessageId() != null) {
                    MessageDO lastMessage = messageMapper.selectById(conv.getLastMessageId());
                    convInfo.put("lastMessage", lastMessage);
                }
                
                return convInfo;
            }).collect(Collectors.toList());

            return JsonData.buildSuccess(result);

        } catch (Exception e) {
            log.error("获取会话列表失败", e);
            return JsonData.buildError("获取会话列表失败");
        }
    }

    @Override
    public JsonData getConversationMessages(String conversationId, int page, int size) {
        try {
            Page<MessageDO> pageParam = new Page<>(page, size);
            QueryWrapper<MessageDO> wrapper = new QueryWrapper<>();
            wrapper.eq("conversation_id", conversationId)
                   .eq("is_deleted", 0)
                   .orderByDesc("create_time");

            IPage<MessageDO> result = messageMapper.selectPage(pageParam, wrapper);

            // 获取发送者信息
            List<MessageDO> messages = result.getRecords();
            for (MessageDO message : messages) {
                UserDO fromUser = userMapper.selectById(message.getFromUserId());
                if (fromUser != null) {
                    message.setMetadata(String.format("{\"fromUserName\":\"%s\",\"fromUserType\":\"%s\"}", 
                                                    fromUser.getName(), fromUser.getType()));
                }
            }

            Map<String, Object> data = new HashMap<>();
            data.put("list", messages);
            data.put("total", result.getTotal());
            data.put("current", result.getCurrent());
            data.put("size", result.getSize());

            return JsonData.buildSuccess(data);

        } catch (Exception e) {
            log.error("获取会话消息失败", e);
            return JsonData.buildError("获取会话消息失败");
        }
    }

    /**
     * 创建或获取会话
     */
    private String getOrCreateConversation(Long user1Id, Long user2Id) {
        // 构建会话参与者ID列表（确保顺序一致）
        List<Long> participants = Arrays.asList(Math.min(user1Id, user2Id), Math.max(user1Id, user2Id));
        String participantsJson = participants.toString();

        QueryWrapper<ConversationDO> wrapper = new QueryWrapper<>();
        wrapper.eq("type", "private")
               .eq("participants", participantsJson);

        ConversationDO conversation = conversationMapper.selectOne(wrapper);
        
        if (conversation == null) {
            // 创建新会话
            String conversationId = UUID.randomUUID().toString().replace("-", "");
            conversation = ConversationDO.builder()
                .id(conversationId)
                .type("private")
                .participants(participantsJson)
                .creatorId(user1Id)
                .isActive(1)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

            conversationMapper.insert(conversation);
            return conversationId;
        }

        return conversation.getId();
    }

    /**
     * 更新会话最后消息
     */
    private void updateConversationLastMessage(String conversationId, Long messageId) {
        ConversationDO conversation = conversationMapper.selectById(conversationId);
        if (conversation != null) {
            conversation.setLastMessageId(messageId);
            conversation.setLastMessageTime(LocalDateTime.now());
            conversation.setUpdateTime(LocalDateTime.now());
            conversationMapper.updateById(conversation);
        }
    }
} 